

                     L                ZZZZZZ         RRRRR           SSSSS
                     L                    Z          R    R         S
                     L          aaa      Z      aaa  R    R  u   u  S
                     L            a     Z         a  RRRRR   u   u  SSSSS
               XX    L         aaaa    Z       aaaa  R    R  u   u       S
              XXXX   L        a   a   Z       a   a  R    R  u   u       S
             XXXXXX  LLLLLLL  aaaaa  ZZZZZZZ  aaaaa  R    R  uuuuu  SSSSSS
             XXXXXX       
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
       XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
             XXXXXX
             XXXXXX
              XXXX        proudly presents his 8.Cracking Tutorial (06.04.1999)
               XX                          HexDecCharEditor 1.02

I.   Tools you need for my tutorial
II.  Cracking with W32Dasm
III. BTW

I.   Tools you need for my tutorial
     Win32Dasm 8.9  (get at http://Qserve.8m.com)
     (perhaps) Soft-Ice for Windows (get at http://Qserve.8m.com)
     A hex-editor, I prefer Hex Workshop 2.54
     HexDecCharEditor 1.02, the target (http://software.webset.de/buschjost/mp3eng.htm
                                  mail me if you don't find the version 1.02 there)
     
II.  Cracking with Win32Dasm:
     OK, let's start cracking. Don't try searching for something with Registry Monitor/File Mon.
     /Helpfile. You won't find anything interesting. Only where the key and the name is saved. 
     But that is of no use (in this case). The target is English and German. I will refer to the
     english strings. The first waypoint is easily found. The string of the "Wrong serial" window
     is hardcoded :) The german strings are always in front of the english strings. It's like 
     that: Calculate serial -> Check it -> If language == English then jump to English -> German
     "Wrong" -> jump to "go on" -> English "Wrong" -> go on
     Ok, you should see this:

     :00435846 8B4DF8                  mov ecx, dword ptr [ebp-08]
     :00435849 8B93E0010000            mov edx, dword ptr [ebx+000001E0]
     :0043584F 8B83DC010000            mov eax, dword ptr [ebx+000001DC]
     :00435855 E8EEC2FFFF              call 00431B48        ;; calculate serial and check it
     :0043585A 84C0                    test al, al          ;; is serial-valid flag = 1
     :0043585C 7432                    je 00435890          ;; then jump to "Beggar off"
     :0043585E C6052065450001          mov byte ptr [00456520], 01
     :00435865 C7832801000001000000    mov dword ptr [ebx+00000128], 00000001
     :0043586F 83BBD801000007          cmp dword ptr [ebx+000001D8], 00000007 ;;language = Germ.?
     :00435876 750C                    jne 00435884 ;; if not then jump to English

     * Possible StringData Ref from Code Obj ->"Vielen Dank f"   ;; german "Thank you"
                                       |
     :00435878 B8E8584300              mov eax, 004358E8
     :0043587D E8EE9DFFFF              call 0042F670
     :00435882 EB30                    jmp 004358B4  ;; jump to "Registered"

     * Referenced by a (U)nconditional or (C)onditional Jump at Address:
     |:00435876(C)
     |
     * Possible StringData Ref from Code Obj ->"Thank you for registering!" ;;english "Thank you"
                                       |
     :00435884 B8185A4300              mov eax, 00435A18
     :00435889 E8E29DFFFF              call 0042F670
     :0043588E EB24                    jmp 004358B4  ;; jump to registered

     * Referenced by a (U)nconditional or (C)onditional Jump at Address:
     |:0043585C(C)                                         ;; here begins the "Beggar off" part
     |
     :00435890 E89F23FDFF              call 00407C34
     :00435895 83BBD801000007          cmp dword ptr [ebx+000001D8], 00000007 ;; language ?
     :0043589C 750C                    jne 004358AA                  ;; if not German then jump

     * Possible StringData Ref from Code Obj ->"Der eingegebene Name und der eingegebenen "
                                             ->"Schl"             ;; German "Wrong key"
                                       |
     :0043589E B8D85A4300              mov eax, 00435AD8
     :004358A3 E8C89DFFFF              call 0042F670 
     :004358A8 EB0A                    jmp 004358B4       ;; keep on unregistered

     * Referenced by a (U)nconditional or (C)onditional Jump at Address:
     |:0043589C(C)
     |

     * Possible StringData Ref from Code Obj ->"Sorry, but the name and the key "   ;; English 
                                        ->"you entered cannot be accepted "         ;; "Wrong"
                                        ->"together. "
                                       |
     :004358AA B8D05B4300              mov eax, 00435BD0
     :004358AF E8BC9DFFFF              call 0042F670

     * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
     |:00435882(U), :0043588E(U), :004358A8(U)
     |
     :004358B4 33C0                    xor eax, eax
     :004358B6 5A                      pop edx
     :004358B7 59                      pop ecx
     :004358B8 59                      pop ecx
     :004358B9 648910                  mov dword ptr fs:[eax], edx

     It seems pretty obvious that the valid key must be calculated deep inside the call at
     :00435855. We will later see, that is so. But what's that. The program will keep on running
     at the same address no matter if the key is valid or not. What does that mean. No saving in
     the registry or somewhere ? No, it must be like this (I didn't check, but that's the only
     way!)
     
     1. Get name and serial from the user
     --- Enter the call ---
     2. Calculate valid serial
     3. Check serials
     4. Set a "Valid" flag
     5. If "Valid" flag set, save into the registry else do nothing
     --- Leave the call ---
     6. If "Valid" flag set, then show "Thank you" else show "Wrong key"
     7. Ok, go on

     We can first check if we can just bypass the jump at :0043585C and perhaps the program saves
     the correct serial or just a "Flag" in the registry so it will be registered next time.
     Forget it!!! The programmer made everything right in order to make my life hard. (Hopefully
     I didn't forget anything real simple) In fact, at the end we will have a crack (2 jumps) 
     that WILL make the target registered, but it will be a damn dirty one. OK, so we have to
     enter the call. You should see this:

     * Referenced by a CALL at Address:
     |:00435855   
     |
     :00431B48 55                      push ebp

     SNIP - SNIP

     :00431BCD E886FEFFFF              call 00431A58
     :00431BD2 8BF0                    mov esi, eax
     :00431BD4 8B4508                  mov eax, dword ptr [ebp+08]
     :00431BD7 E8EC3EFDFF              call 00405AC8
     :00431BDC 3BF0                    cmp esi, eax                    
     :00431BDE 0F8533010000            jne 00431D17                    ;; Beggar off
     :00431BE4 8B45F8                  mov eax, dword ptr [ebp-08]
     :00431BE7 E8A819FDFF              call 00403594
     :00431BEC 83F80A                  cmp eax, 0000000A
     :00431BEF 0F8C22010000            jl 00431D17                     ;; Beggar off
     :00431BF5 B201                    mov dl, 01
     :00431BF7 B8E8F74200              mov eax, 0042F7E8
     :00431BFC E89BDCFFFF              call 0042F89C  
     :00431C01 8945E8                  mov dword ptr [ebp-18], eax
     :00431C04 33C0                    xor eax, eax
 
     SNIP - SNIP

     :00431CF5 E87617FDFF              call 00403470

     * Referenced by a (U)nconditional or (C)onditional Jump at Address:
     |:00431C46(C)
     |  
     :00431CFA 33C0                    xor eax, eax                   ;; set "Wrong" flag
     :00431CFC 5A                      pop edx
     :00431CFD 59                      pop ecx
     :00431CFE 59                      pop ecx
     :00431CFF 648910                  mov dword ptr fs:[eax], edx
     :00431D02 68171D4300              push 00431D17

     * Referenced by a (U)nconditional or (C)onditional Jump at Address:
     |:00431D15(U)
     |
     :00431D07 8B45E8                  mov eax, dword ptr [ebp-18]
     :00431D0A E8690EFDFF              call 00402B78
     :00431D0F C3                      ret                           ;; Return from Call


     OK, right in front of the first "Beggar off" jump we see a call and a CMP ESI, EAX and this
     compare sets the "Wrong" flag if they are not the same. When I tell you ESI contains the 
     hex value of the entered serial what do you say contains the EAX. WRONG!!! It doesn't
     contain the correct serial. I didn't believe it. This obvious compare and no valid serial.
     That's strange. At least I was able to find out, that the next "Beggar off" is set, when
     the name contains less than 10 characters :). 
     OK, no idea how to get the valid serial again. So the old bypass-and-hope method. And this
     time it really works :). When you no-op the jump at :00431BDE and at :00431BEF you can
     register the target (and even with less than 10-char-names). HexDecCharEditor will write
     the correct code to the registry and the program will be registered next time you start it.
     But don't believe the code you can enter in the "Register" box is written to the registry.
     Everytime you register it another code is written to the registry (even if you don't change
     the name). For LaZaRuS I got (for example):

     HKEY_LOCAL_MACHINE\SOFTWARE\Beyersdorf\HexDecCharEditor\Key = 97C5FF823C8B
     HKEY_LOCAL_MACHINE\SOFTWARE\Beyersdorf\HexDecCharEditor\Key = 5312DDA92340
     HKEY_LOCAL_MACHINE\SOFTWARE\Beyersdorf\HexDecCharEditor\Key = 5C738FDB49C5
     HKEY_LOCAL_MACHINE\SOFTWARE\Beyersdorf\HexDecCharEditor\Key = 24588FE844E3
     ...

     So, if you see more than I do, why not write a tutorial about it. Or if you don't write one
     please tell me at least the important facts I found out.


III. BTW
     Hope my tutorial was helpful for you and see you again in my next tutorial. 
     
     Greets to: Fravia+, tKC, ED!SON, Moral Insanity, The Sandman, Eternal Bliss, DaVinci and 
     all [hf] members


All Tutorials by LaZaRuS [hf]

#|  date  |   name           |version|W32Dasm|Soft-Ice|kind of crack            |
-|--------|------------------|-------|-------|--------|-------------------------|
1|20.01.99|Jaylock           |1,0,0,1|  (X)  |   (X)  |serial#                  |
2|31.01.99|Goldwave          |4.02   |  (X)  |   (X)  |serial#,nag-screens      |
3|28.03.99|AxMan             |3.00   |  (X)  |   (X)  |serial#,remove date-limit|
 |        |                  |       |       |        |nag-screen, key generator|
4|29.03.99|C++Builder Strings|       |  (X)  |   (X)  |how to find strings in   |
 |        |                  |       |       |        |C++ Builder that are not |
 |        |                  |       |       |        |hardcoded                |
5|29.03.99|Better Protection |       |       |        |How to protect shareware |
 |        |                  |       |       |        |better against crackers  |
6|04.04.99|Start Clean       |1.2    |  (X)  |   (X)  |nag-screen/serial/keygen |
7|06.04.99|MP3 TO EXE        |1.02   |  (X)  |   (X)  |nag-screen/serial        |
8|06.04.99|HexDecCharEditor  |1.02   |  (X)  |        |make it registered       |

     
LaZaRuS [hf]
Visit Hellforge at http://members.xoom.com/hell_crack for more tutorials and high quality
cracking links.
If you want to mail me: lazarus666@gnwmail.com